﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Siser.Web.Models;

namespace Siser.Web.Shared
{
    public static class SystemAlarm
    {
        private static SiserEntities db = new SiserEntities();

        public static string GetAlarmLevelByRegion(string userName, int? regionId = null)
        {
            var detectores = (from e in db.Equipos
                              join ue in db.UsuariosEquipos on e.Id equals ue.EquipoId
                              join u in db.Usuarios on ue.UsuarioId equals u.Id
                              join ep in db.EquiposPiezas on e.Id equals ep.EquipoId
                              join p in db.Piezas on ep.PiezaId equals p.Id
                              where ep.FechaFin == null
                                 && p.TipoPieza.Nombre == "Detector"
                                 && p.Vigencia == true
                                 && u.Vigencia == true
                                 && u.Nombre == userName
                                 && (e.Instalacion.Planta.RegionId == regionId || regionId == null)
                              select p).ToList();

            return GetAlarmLevelForDetectores(detectores);
        }

        public static string GetAlarmLevelByPlanta(string userName, int? plantaId = null)
        {
            var detectores = (from e in db.Equipos
                              join ue in db.UsuariosEquipos on e.Id equals ue.EquipoId
                              join u in db.Usuarios on ue.UsuarioId equals u.Id
                              join ep in db.EquiposPiezas on e.Id equals ep.EquipoId
                              join p in db.Piezas on ep.PiezaId equals p.Id
                              where ep.FechaFin == null
                                 && p.TipoPieza.Nombre == "Detector"
                                 && p.Vigencia == true
                                 && u.Vigencia == true
                                 && u.Nombre == userName
                                 && (e.Instalacion.PlantaId == plantaId || plantaId == null)
                              select p).ToList();

            return GetAlarmLevelForDetectores(detectores);
        }

        public static string GetAlarmLevelByInstalacion(string userName, int? instalacionId = null)
        {
            var detectores = (from e in db.Equipos
                              join ue in db.UsuariosEquipos on e.Id equals ue.EquipoId
                              join u in db.Usuarios on ue.UsuarioId equals u.Id
                              join ep in db.EquiposPiezas on e.Id equals ep.EquipoId
                              join p in db.Piezas on ep.PiezaId equals p.Id
                              where ep.FechaFin == null
                                 && p.TipoPieza.Nombre == "Detector"
                                 && p.Vigencia == true
                                 && u.Vigencia == true
                                 && u.Nombre == userName
                                 && (e.InstalacionId == instalacionId || instalacionId == null)
                              select p).ToList();

            return GetAlarmLevelForDetectores(detectores);
        }

        public static string GetAlarmLevelByEquipo(string userName, int? equipoId = null)
        {
            var detectores = (from e in db.Equipos
                              join ue in db.UsuariosEquipos on e.Id equals ue.EquipoId
                              join u in db.Usuarios on ue.UsuarioId equals u.Id
                              join ep in db.EquiposPiezas on e.Id equals ep.EquipoId
                              join p in db.Piezas on ep.PiezaId equals p.Id
                              where ep.FechaFin == null
                                 && p.TipoPieza.Nombre == "Detector"
                                 && p.Vigencia == true
                                 && u.Vigencia == true
                                 && u.Nombre == userName
                                 && (e.Id == equipoId || equipoId == null)
                              select p).ToList();

            return GetAlarmLevelForDetectores(detectores);
        }

        public static string GetAlarmLevelByDetector(string userName, int? piezaId = null)
        {
            var detectores = (from e in db.Equipos
                              join ue in db.UsuariosEquipos on e.Id equals ue.EquipoId
                              join u in db.Usuarios on ue.UsuarioId equals u.Id
                              join ep in db.EquiposPiezas on e.Id equals ep.EquipoId
                              join p in db.Piezas on ep.PiezaId equals p.Id
                              where ep.FechaFin == null
                                 && p.TipoPieza.Nombre == "Detector"
                                 && p.Vigencia == true
                                 && u.Vigencia == true
                                 && u.Nombre == userName
                                 && (p.Id == piezaId || piezaId == null)
                              select p).ToList();

            return GetAlarmLevelForDetectores(detectores);
        }

        private static string GetAlarmLevelForDetectores(List<Pieza> detectores)
        {
            List<Alarma> alarmasDeclaradas = new List<Alarma>();

            foreach (Pieza pieza in detectores)
            {
                var ultimaAlarma = (from a in db.Alarmas
                                    join na in db.NivelesAlarmas on a.NivelAlarmaId equals na.Id
                                    where a.PiezaId == pieza.Id
                                    orderby a.Fecha descending
                                    select a).Take(1).FirstOrDefault();

                if (ultimaAlarma != null)
                {
                    // Criterio para declarar alarma:
                    // Existir un registro en la tabla alarmas sin nuevas mediciones no alarmadas en la tabla mediciones
                    var ultimaMedicion = (from m in db.Mediciones
                                          where m.PiezaId == ultimaAlarma.PiezaId
                                             && m.Fecha > ultimaAlarma.Fecha
                                          select m).Take(1).FirstOrDefault();

                    if (ultimaMedicion == null)
                        alarmasDeclaradas.Add(ultimaAlarma);
                }
            }

            var alarma = (from a in alarmasDeclaradas
                          orderby a.NivelAlarma.Criticidad descending
                          select a).FirstOrDefault();

            if (alarma != null)
            {
                if (alarma.NivelAlarma.Nombre != "Registro")
                {
                    if (alarma.NivelAlarma.Nombre == "Investigación")
                        return "INVESTIGACION";
                    if (alarma.NivelAlarma.Nombre == "Intervención")
                        return "INTERVENCION";
                }
            }

            return "";
        }
    }
}